package tests;

import junit.framework.TestCase;
import model.*;

import java.util.ArrayList;

/**
 * Se prueba que los fantasmas y el pacman se muevan como se espera según el 
 * escenario de prueba creado. 
 * Se chequea que cuando el fantasma caza al pacman termine el juego.
 * Se prueba que los fantasmas aumenten su agresividad cada 30 turnos.
 * 
 * @author Juan Marchese (juan.marchese@fdvsolutions.com)
 *         Date: 21/06/12
 *         Time: 15:43
 */
public class EscenarioTest extends TestCase {
	
	Escenario escenario;
	
	protected void setUp() {
		this.escenario = new Escenario();
	}
		
	/**
	 * Escenario de prueba
	 * 
     * 	   0-1-2-3
	 *	0  p-p-p-p
	 *	1  p-p-c-p
	 *	2  p-c-c-p
	 *	3  p-p-p-p
	 *
	 */
	public void testMoverPacmanAderecha(){
		
		//POR DEFAULT EL CAMINO INSTANCIA UNA BOLITA
        this.escenario.setY(new Entero(2));
        this.escenario.setX(new Entero(2));
			
        ArrayList<ElemEscenario> columna = new ArrayList<ElemEscenario>();
        columna.add(new Pared(0, 0));
        columna.add(new Pared(1, 0));
        columna.add(new Pared(2, 0));
        columna.add(new Pared(3, 0));
        escenario.getLaberinto().add(columna); //Columna 0
				
        columna = new ArrayList<ElemEscenario>();
        columna.add(new Pared(0,1));
        columna.add(new Pared(1,1));
        escenario.setPosicionInicialPacman(new Camino(2,1));
        columna.add(escenario.getPosicionInicialPacman());
        columna.add(new Pared(3,1));
        escenario.getLaberinto().add(columna); //Columna 1

        columna = new ArrayList<ElemEscenario>();
        columna.add(new Pared(0,2));
        escenario.setPosicionGuaridaFantasmas(new Camino(1,2, true));
        columna.add(escenario.getPosicionGuaridaFantasmas());
        columna.add(new Camino(2,2));
        columna.add(new Pared(3,2));
        escenario.getLaberinto().add(columna); //Columna 2
                
        columna = new ArrayList<ElemEscenario>();
        columna.add(new Pared(0,3));
        columna.add(new Pared(1,3));
        columna.add(new Pared(2,3));
        columna.add(new Pared(3,3));
        escenario.getLaberinto().add(columna); //Columna 3
        
        escenario.buildPersonajesEscenario();
        
        assertEquals("testMoverPacmanAderecha",true,escenario.moverPacman(2,Constantes.DERECHA));
               
	}
	
	/**
	 * Escenario de prueba
	 * 
     * 	   0-1-2-3
	 *	0  p-p-p-p
	 *	1  p-p-c-p
	 *	2  p-c-c-p
	 *	3  p-p-p-p
	 *
	 */
	public void testMoverPacmanAizquierda(){
		
		//POR DEFAULT EL CAMINO INSTANCIA UNA BOLITA
        this.escenario.setY(new Entero(2));
        this.escenario.setX(new Entero(2));
			
        ArrayList<ElemEscenario> columna = new ArrayList<ElemEscenario>();
        columna.add(new Pared(0, 0));
        columna.add(new Pared(1, 0));
        columna.add(new Pared(2, 0));
        columna.add(new Pared(3, 0));
        escenario.getLaberinto().add(columna); //Columna 0
				
        columna = new ArrayList<ElemEscenario>();
        columna.add(new Pared(0,1));
        columna.add(new Pared(1,1));
        escenario.setPosicionInicialPacman(new Camino(2,1));
        columna.add(escenario.getPosicionInicialPacman());
        columna.add(new Pared(3,1));
        escenario.getLaberinto().add(columna); //Columna 1

        columna = new ArrayList<ElemEscenario>();
        columna.add(new Pared(0,2));
        escenario.setPosicionGuaridaFantasmas(new Camino(1,2, true));
        columna.add(escenario.getPosicionGuaridaFantasmas());
        columna.add(new Camino(2,2));
        columna.add(new Pared(3,2));
        escenario.getLaberinto().add(columna); //Columna 2
                
        columna = new ArrayList<ElemEscenario>();
        columna.add(new Pared(0,3));
        columna.add(new Pared(1,3));
        columna.add(new Pared(2,3));
        columna.add(new Pared(3,3));
        escenario.getLaberinto().add(columna); //Columna 3
        
        escenario.buildPersonajesEscenario();
        
        assertEquals("testMoverPacmanAizquierda",false,escenario.moverPacman(2,Constantes.IZQUIERDA)); //porque a izquierda tiene una pared y no se puede mover
               
	}
	
	/**
	 * Escenario de prueba
	 * 
     * 	   0-1-2-3
	 *	0  p-p-p-p
	 *	1  p-c-c-p
	 *	2  p-c-c-p
	 *	3  p-p-p-p
	 *
	 */
	public void testMoverPacmanAarriba(){
		
		//POR DEFAULT EL CAMINO INSTANCIA UNA BOLITA
        this.escenario.setY(new Entero(2));
        this.escenario.setX(new Entero(2));
			
        ArrayList<ElemEscenario> columna = new ArrayList<ElemEscenario>();
        columna.add(new Pared(0, 0));
        columna.add(new Pared(1, 0));
        columna.add(new Pared(2, 0));
        columna.add(new Pared(3, 0));
        escenario.getLaberinto().add(columna); //Columna 0
				
        columna = new ArrayList<ElemEscenario>();
        columna.add(new Pared(0,1));
        columna.add(new Camino(1,1));
        escenario.setPosicionInicialPacman(new Camino(2,1));
        columna.add(escenario.getPosicionInicialPacman());
        columna.add(new Pared(3,1));
        escenario.getLaberinto().add(columna); //Columna 1

        columna = new ArrayList<ElemEscenario>();
        columna.add(new Pared(0,2));
        escenario.setPosicionGuaridaFantasmas(new Camino(1,2, true));
        columna.add(escenario.getPosicionGuaridaFantasmas());
        columna.add(new Camino(2,2));
        columna.add(new Pared(3,2));
        escenario.getLaberinto().add(columna); //Columna 2
                
        columna = new ArrayList<ElemEscenario>();
        columna.add(new Pared(0,3));
        columna.add(new Pared(1,3));
        columna.add(new Pared(2,3));
        columna.add(new Pared(3,3));
        escenario.getLaberinto().add(columna); //Columna 3
        
        escenario.buildPersonajesEscenario();
        
        assertEquals("testMoverPacmanAarriba",true,escenario.moverPacman(2,Constantes.ARRIBA)); //porque a izquierda tiene una pared y no se puede mover
               
	}
	
	/**
	 * Escenario de prueba
	 * 
     * 	   0-1-2-3
	 *	0  p-p-p-p
	 *	1  p-c-c-p
	 *	2  p-c-c-p
	 *	3  p-p-p-p
	 *
	 */
	public void testMoverPacmanAabajo(){
		
		//POR DEFAULT EL CAMINO INSTANCIA UNA BOLITA
        this.escenario.setY(new Entero(2));
        this.escenario.setX(new Entero(2));
			
        ArrayList<ElemEscenario> columna = new ArrayList<ElemEscenario>();
        columna.add(new Pared(0, 0));
        columna.add(new Pared(1, 0));
        columna.add(new Pared(2, 0));
        columna.add(new Pared(3, 0));
        escenario.getLaberinto().add(columna); //Columna 0
				
        columna = new ArrayList<ElemEscenario>();
        columna.add(new Pared(0,1));
        columna.add(new Camino(1,1));
        escenario.setPosicionInicialPacman(new Camino(2,1));
        columna.add(escenario.getPosicionInicialPacman());
        columna.add(new Pared(3,1));
        escenario.getLaberinto().add(columna); //Columna 1

        columna = new ArrayList<ElemEscenario>();
        columna.add(new Pared(0,2));
        escenario.setPosicionGuaridaFantasmas(new Camino(1,2, true));
        columna.add(escenario.getPosicionGuaridaFantasmas());
        columna.add(new Camino(2,2));
        columna.add(new Pared(3,2));
        escenario.getLaberinto().add(columna); //Columna 2
                
        columna = new ArrayList<ElemEscenario>();
        columna.add(new Pared(0,3));
        columna.add(new Pared(1,3));
        columna.add(new Pared(2,3));
        columna.add(new Pared(3,3));
        escenario.getLaberinto().add(columna); //Columna 3
        
        escenario.buildPersonajesEscenario();
        
        assertEquals("testMoverPacmanAabajo",false,escenario.moverPacman(2,Constantes.ABAJO)); //porque abajo tiene una pared y no se puede mover
               
	}
	
	/**
	 * Escenario de prueba
	 * 
     * 	   0-1-2-3
	 *	0  p-p-p-p
	 *	1  p-c-c-p
	 *	2  T-c-c-T
	 *	3  p-p-p-p
	 *
	 */
	public void testTeletransportarPacmanDesdeY2X1HastaY2X2(){
		
		//POR DEFAULT EL CAMINO INSTANCIA UNA BOLITA
        this.escenario.setY(new Entero(2));
        this.escenario.setX(new Entero(2));
			
        ArrayList<ElemEscenario> columna = new ArrayList<ElemEscenario>();
        columna.add(new Pared(0, 0));
        columna.add(new Pared(1, 0));
        columna.add(new Transportador(2,0,2,2)); // teletransporta al camino y=2, x=2
        columna.add(new Pared(3, 0));
        escenario.getLaberinto().add(columna); //Columna 0
				
        columna = new ArrayList<ElemEscenario>();
        columna.add(new Pared(0,1));
        columna.add(new Camino(1,1));
        escenario.setPosicionInicialPacman(new Camino(2,1));
        columna.add(escenario.getPosicionInicialPacman());
        columna.add(new Pared(3,1));
        escenario.getLaberinto().add(columna); //Columna 1

        columna = new ArrayList<ElemEscenario>();
        columna.add(new Pared(0,2));
        escenario.setPosicionGuaridaFantasmas(new Camino(1,2, true));
        columna.add(escenario.getPosicionGuaridaFantasmas());
        columna.add(new Camino(2,2));
        columna.add(new Pared(3,2));
        escenario.getLaberinto().add(columna); //Columna 2
                
        columna = new ArrayList<ElemEscenario>();
        columna.add(new Pared(0,3));
        columna.add(new Pared(1,3));
        columna.add(new Transportador(2,3,2,1)); // teletransporta al camino y=2, x=1
        columna.add(new Pared(3,3));
        escenario.getLaberinto().add(columna); //Columna 3
        
        escenario.buildPersonajesEscenario();
        
        escenario.moverPacman(2,Constantes.IZQUIERDA);
        
        Camino caminoSiguiente = new Camino(2,2);
                
        assertEquals("testTeletransportarPacmanDesdeY2X1HastaY2X2",true,escenario.getPacMan().getPosicion().equals(caminoSiguiente)); //porque abajo tiene una pared y no se puede mover
               
	}
	
	/**
	 * Escenario de prueba
	 * 
     * 	   0-1-2-3
	 *	0  p-T-p-p
	 *	1  p-c-c-p
	 *	2  p-c-c-p
	 *	3  p-T-p-p
	 *
	 */
	public void testTeletransportarPacmanDesdeY1X1HastaY2X1(){
		
		//POR DEFAULT EL CAMINO INSTANCIA UNA BOLITA
        this.escenario.setY(new Entero(2));
        this.escenario.setX(new Entero(2));
			
        ArrayList<ElemEscenario> columna = new ArrayList<ElemEscenario>();
        columna.add(new Pared(0, 0));
        columna.add(new Pared(1, 0));
        columna.add(new Pared(2,0)); 
        columna.add(new Pared(3, 0));
        escenario.getLaberinto().add(columna); //Columna 0
				
        columna = new ArrayList<ElemEscenario>();
        columna.add(new Transportador(0,1,2,1)); // teletransporta al camino y=2, x=1
        escenario.setPosicionInicialPacman(new Camino(1,1));
        columna.add(escenario.getPosicionInicialPacman());
        columna.add(new Camino(2,1));
        columna.add(new Transportador(3,1,1,1)); // teletransporta al camino y=1, x=1
        escenario.getLaberinto().add(columna); //Columna 1

        columna = new ArrayList<ElemEscenario>();
        columna.add(new Pared(0,2));
        escenario.setPosicionGuaridaFantasmas(new Camino(1,2, true));
        columna.add(escenario.getPosicionGuaridaFantasmas());
        columna.add(new Camino(2,2));
        columna.add(new Pared(3,2));
        escenario.getLaberinto().add(columna); //Columna 2
                
        columna = new ArrayList<ElemEscenario>();
        columna.add(new Pared(0,3));
        columna.add(new Pared(1,3));
        columna.add(new Pared(2,3)); 
        columna.add(new Pared(3,3));
        escenario.getLaberinto().add(columna); //Columna 3
        
        escenario.buildPersonajesEscenario();
        
        escenario.moverPacman(2,Constantes.ARRIBA);
        
        Camino caminoSiguiente = new Camino(2,1);
                
        assertEquals("testTeletransportarPacmanDesdeY2X1HastaY2X2",true,escenario.getPacMan().getPosicion().equals(caminoSiguiente)); //porque abajo tiene una pared y no se puede mover
               
	}
	
	/**
	 * Valor esperado: Todos los fantasmas se pueden mover desde la posicion Y2, X1 (guarida) a la posicion Y2, X2 
	 * 
     * 	   0-1-2-3
	 *	0  p-p-p-p
	 *	1  p-p-c-p
	 *	2  p-c-c-p
	 *	3  p-p-p-p
	 *
	 */
	public void testMoverFantasmas(){
		
		//POR DEFAULT EL CAMINO INSTANCIA UNA BOLITA
        this.escenario.setY(new Entero(2));
        this.escenario.setX(new Entero(2));
			
        ArrayList<ElemEscenario> columna = new ArrayList<ElemEscenario>();
        columna.add(new Pared(0, 0));
        columna.add(new Pared(1, 0));
        columna.add(new Pared(2,0)); 
        columna.add(new Pared(3, 0));
        escenario.getLaberinto().add(columna); //Columna 0
				
        columna = new ArrayList<ElemEscenario>();
        columna.add(new Pared(0,1));
        columna.add(new Pared(1,1));
        escenario.setPosicionInicialPacman(new Camino(2,1));
        columna.add(escenario.getPosicionInicialPacman());
        columna.add(new Pared(3,1));
        escenario.getLaberinto().add(columna); //Columna 1

        columna = new ArrayList<ElemEscenario>();
        columna.add(new Pared(0,2));
        escenario.setPosicionGuaridaFantasmas(new Camino(1,2, true));
        columna.add(escenario.getPosicionGuaridaFantasmas());
        columna.add(new Camino(2,2));
        columna.add(new Pared(3,2));
        escenario.getLaberinto().add(columna); //Columna 2
                
        columna = new ArrayList<ElemEscenario>();
        columna.add(new Pared(0,3));
        columna.add(new Pared(1,3));
        columna.add(new Pared(2,3)); 
        columna.add(new Pared(3,3));
        escenario.getLaberinto().add(columna); //Columna 3
        
        escenario.buildPersonajesEscenario();
                                            
        assertEquals("testTeletransportarPacmanDesdeY2X1HastaY2X2",true,escenario.moverFantasmas(3));
               
	}
	
	/**
	 * Prueba Fantasma caza a pacman. Fin del juego
	 * 
	 *	   0-1-2-3
	 *	0  p-p-p-p
	 *	1  p-p-c-p
	 *	2  p-c-B-p
	 *	3  p-p-p-p
	 * 
	 */
	public void testFinDeJuego(){
		//POR DEFAULT EL CAMINO INSTANCIA UNA BOLITA
        this.escenario.setY(new Entero(2));
        this.escenario.setX(new Entero(2));
			
        ArrayList<ElemEscenario> columna = new ArrayList<ElemEscenario>();
        columna.add(new Pared(0, 0));
        columna.add(new Pared(1, 0));
        columna.add(new Pared(2, 0));
        columna.add(new Pared(3, 0));
        escenario.getLaberinto().add(columna); //Columna 0
				
        columna = new ArrayList<ElemEscenario>();
        columna.add(new Pared(0,1));
        columna.add(new Pared(1,1));
        escenario.setPosicionInicialPacman(new Camino(2,1));
        columna.add(escenario.getPosicionInicialPacman());
        columna.add(new Pared(3,1));
        escenario.getLaberinto().add(columna); //Columna 1

        columna = new ArrayList<ElemEscenario>();
        columna.add(new Pared(0,2));
        escenario.setPosicionGuaridaFantasmas(new Camino(1,2, true));
        columna.add(escenario.getPosicionGuaridaFantasmas());
        columna.add(new Camino(2,2,new Bolon()));
        columna.add(new Pared(3,2));
        escenario.getLaberinto().add(columna); //Columna 2
                
        columna = new ArrayList<ElemEscenario>();
        columna.add(new Pared(0,3));
        columna.add(new Pared(1,3));
        columna.add(new Pared(2,3));
        columna.add(new Pared(3,3));
        escenario.getLaberinto().add(columna); //Columna 3
        
        escenario.buildPersonajesEscenario();
        escenario.moverPacman(2, Constantes.DERECHA);
        escenario.moverFantasmas(3);
        escenario.actualizarEstado();
   
		assertEquals("testFinDeJuego", true, escenario.checkearFinDeJuego());
	}
	
	/**
	 * Se prueba que aumente la agresividad del pacman cada 30 turnos, que pase por los estados de cazador normal a 
	 * cazador molesto, y de cazador molesto a cazador agresivo.
	 * 
	 *	   0-1-2-3-4
	 *	0  p-p-p-p-p
	 *	1  p-p-c-p-p
	 *	2  p-p-B-c-p
	 *	3  p-c-c-c-p
	 *  4  p-p-p-p-p 
	 *  
	 */
	public void testAumentarAgresividadFantasmas(){
		//POR DEFAULT EL CAMINO INSTANCIA UNA BOLITA
        this.escenario.setY(new Entero(2));
        this.escenario.setX(new Entero(2));
        		
        ArrayList<ElemEscenario> columna = new ArrayList<ElemEscenario>();
        columna.add(new Pared(0, 0));
        columna.add(new Pared(1, 0));
        columna.add(new Pared(2, 0));
        columna.add(new Pared(3, 0));
        columna.add(new Pared(4, 0));
        escenario.getLaberinto().add(columna); //Columna 0
				
        columna = new ArrayList<ElemEscenario>();
        columna.add(new Pared(0,1));
        columna.add(new Pared(1,1));
        columna.add(new Pared(2,1));
        escenario.setPosicionInicialPacman(new Camino(3,1));
        columna.add(escenario.getPosicionInicialPacman());
        columna.add(new Pared(4,1));
        escenario.getLaberinto().add(columna); //Columna 1

        columna = new ArrayList<ElemEscenario>();
        columna.add(new Pared(0,2));
        escenario.setPosicionGuaridaFantasmas(new Camino(1,2, true));
        columna.add(escenario.getPosicionGuaridaFantasmas());
        columna.add(new Camino(2,2,new Bolon()));
        columna.add(new Camino(3,2));
        columna.add(new Pared(4,2));
        escenario.getLaberinto().add(columna); //Columna 2
                
        columna = new ArrayList<ElemEscenario>();
        columna.add(new Pared(0,3));
        columna.add(new Pared(1,3));
        columna.add(new Camino(2,3));
        columna.add(new Camino(3,3));
        columna.add(new Pared(4,3));
        escenario.getLaberinto().add(columna); //Columna 3
        
        columna = new ArrayList<ElemEscenario>();
        columna.add(new Pared(0,4));
        columna.add(new Pared(1,4));
        columna.add(new Pared(2,4));
        columna.add(new Pared(3,4));
        columna.add(new Pared(4,4));
        escenario.getLaberinto().add(columna); //Columna 4
           
        escenario.buildPersonajesEscenario();
        escenario.moverPacman(2, Constantes.DERECHA);
        
        Juego.getInstance().setTurno(30); //cada 30 turnos cambia de estado los fantasmas
       	escenario.moverFantasmas(3);
        escenario.actualizarEstado();
                    
        boolean isEstadosFantasmasEsperado=true;
        
        for (Fantasma fantasma : escenario.getFantasmas()) {
        	isEstadosFantasmasEsperado=(fantasma.mostrarEstado().equalsIgnoreCase("cazadorMolesto")==true)?isEstadosFantasmasEsperado:false;
		}
   
		assertEquals("testAumentarAgresividadFantasmas", true, isEstadosFantasmasEsperado);
		
		Juego.getInstance().setTurno(30); //cada 30 turnos cambia de estado los fantasmas
		escenario.moverFantasmas(3);
		escenario.actualizarEstado();

		isEstadosFantasmasEsperado=true;

		for (Fantasma fantasma : escenario.getFantasmas()) {
			isEstadosFantasmasEsperado=(fantasma.mostrarEstado().equalsIgnoreCase("cazadorFurioso")==true)?isEstadosFantasmasEsperado:false;
		}

		assertEquals("testAumentarAgresividadFantasmas", true, isEstadosFantasmasEsperado);
	}
}
